import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { APP_GUARD } from '@nestjs/core';
import { TypeOrmModule } from '@nestjs/typeorm';
import { WinstonModule } from 'nest-winston';

import configuration from '@src/config/configuration';
import { envValidation } from '@src/config/env.validation';
import { HttpExampleController } from '@src/http-example/http-example.controller';
import { AuthModule } from '@src/auth/auth.module';
import { UsersModule } from '@src/users/users.module';
import { JwtAuthGuard } from '@src/auth/guard/jwt-auth.guard';
import { ConfigurationModule } from '@src/config/configuration.module';
import { ConfigurationService } from '@src/config/configuration.service';
import { winstonConfigFactory } from '@src/config/winston';
import { databaseConfigFactory } from '@src/config/database';
import { DatabaseModule } from '@src/database/database.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [configuration],
      validationSchema: envValidation,
    }),
    ConfigurationModule,
    WinstonModule.forRootAsync({
      imports: [ConfigurationModule],
      inject: [ConfigurationService],
      useFactory: (configurationService: ConfigurationService) => {
        return winstonConfigFactory(configurationService);
      },
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigurationModule],
      inject: [ConfigurationService],
      useFactory: (configurationService: ConfigurationService) => {
        return databaseConfigFactory(configurationService);
      },
    }),
    DatabaseModule,
    AuthModule,
    UsersModule,
  ],
  controllers: [HttpExampleController],
  providers: [
    {
      provide: APP_GUARD,
      useClass: JwtAuthGuard,
    },
  ],
})
export class AppModule {}
